home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 1.iso
/
toolbox
/
src
/
exampleCode
/
opengl
/
glx
/
font.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-11
|
7KB
|
299 lines
/*
* Copyright (C) 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* 1993 Simon Hui -- Silicon Graphics Computer Systems
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glu.h>
#include <X11/keysym.h>
#include "util.h"
#define W 600
#define H 600
#define FONT1 \
"-adobe-itc avant garde gothic-demi-o-normal--25-180-100-100-p-139-iso8859-1"
#define FONT2 "10x20"
/*
** The base for display list of entire font.
*/
#define FONTBASE 0x1000
/*
** The base for display list of just the alphabet.
*/
#define ALPHABETBASE 0x8000
#define DRAW_ALL 1
#define DRAW_ALPHABET 2
#define DRAW_RAINBOW 3
static long width = W, height = H;
GC xgc;
Display *dpy;
Colormap cmap;
Window win;
GLXContext cx;
XFontStruct *fontStruct;
XVisualInfo *vi;
char *theString = "OpenGL";
char *fontName;
int mode = DRAW_RAINBOW;
int glyphs, rows, cols, first, last;
int firstRow, lastRow;
static void Init(void)
{
XGCValues gcvalues;
int fg;
fontStruct = XLoadQueryFont(dpy, FONT1);
if (!fontStruct) {
/* if the avant-garde font is not avail, try the simpler 10x20 font */
fontStruct = XLoadQueryFont(dpy, FONT2);
if (!fontStruct) {
fprintf(stderr, "font %s not found\n", FONT2);
exit(1);
}
}
firstRow = fontStruct->min_byte1;
lastRow = fontStruct->max_byte1;
rows = lastRow - firstRow + 1;
if (rows > 5) {
printf ("only using first 5 rows of this multi-row font\n");
rows = 5;
lastRow = firstRow + rows - 1;
}
first = fontStruct->min_char_or_byte2;
last = fontStruct->max_char_or_byte2;
cols = last - first + 1;
glyphs = cols;
/*
** Define bitmaps for entire font.
*/
glXUseXFont(fontStruct->fid, firstRow << 8, rows*256, FONTBASE);
/*
** Define bitmaps for just the alphabet.
*/
glXUseXFont(fontStruct->fid, 'A', 26, ALPHABETBASE);
gcvalues.foreground = utilXPixel(0, 0, 0, vi);
gcvalues.background = utilXPixel(0, 1, 0, vi);
gcvalues.font = fontStruct->fid;
XChangeGC(dpy, xgc, GCForeground|GCBackground|GCFont, &gcvalues);
XDrawString(dpy, win, xgc, W/2, H/2, theString, strlen(theString));
XFlush(dpy);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-0.1, 1.1, -0.1, 1.1, 0, 1);
glMatrixMode(GL_MODELVIEW);
glClearColor(1.0, 0.0, 1.0, 0.0);
}
static void DrawAll(void)
{
int r;
int i, j, c;
int nrow, ncol=16;
char buf[20];
glColor3f(0.0, 0.0, 1.0);
for (r=0; r < rows; r++) {
glClear( GL_COLOR_BUFFER_BIT );
c = FONTBASE + (r<<8);
for (j=15; j > -1; j--) {
for (i=0; i < 16; i++) {
glRasterPos2f((float)i/16.0, (float)j/16.0);
glCallList(c);
c++;
}
}
glFlush();
if (rows > 1) {
printf( "hit return to see next row of font>" );
gets(buf);
}
}
}
static void DrawAlphabet(void)
{
int i, j, c;
int nrow=16, ncol=16;
glColor3f(1.0, 0.0, 0.0);
for (j=0; j < nrow; j++) {
for (i=0; i < ncol; i++) {
glRasterPos2f((float)i/ncol, (float)j/nrow);
c = (j*ncol + i) % 26;
glCallList(ALPHABETBASE + c);
}
}
}
static float colors[][3] = {
{1, 0, 0},
{1, 1, 0},
{0, 1, 1},
{1, 0, 1},
{0, 0, 1},
};
void DrawRainbow(void)
{
int i, ncolors, nrows, h;
float *this, *next;
float r, g, b;
float x, y, dx, dy;
h = fontStruct->max_bounds.ascent + fontStruct->max_bounds.descent;
ncolors = sizeof(colors) / sizeof(colors[0]);
nrows = 10;
dx = 1.0 / ncolors;
dy = 1.0 / nrows;
glListBase(FONTBASE);
x = 0;
for (i=0; i < ncolors; i++) {
for (y=0; y < 1; y+=dy) {
this = colors[i];
next = colors[(i+1)%ncolors];
r = (y*next[0]) + (1-y)*this[0];
g = (y*next[1]) + (1-y)*this[1];
b = (y*next[2]) + (1-y)*this[2];
glColor3f(r, g, b);
glRasterPos2f(x, y);
glCallLists(strlen(theString), GL_BYTE, (GLubyte *)theString);
}
x += dx;
}
XDrawString(dpy, win, xgc, W/2, H/2, theString, strlen(theString));
}
void DoDisplay(void)
{
glClearColor(.5, .5, .5, 1);
glClear(GL_COLOR_BUFFER_BIT);
switch(mode) {
case DRAW_ALL:
DrawAll();
break;
case DRAW_ALPHABET:
DrawAlphabet();
break;
case DRAW_RAINBOW:
DrawRainbow();
break;
}
glFlush();
}
static int attributes[] = {
GLX_RGBA,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
None,
};
static void usage(void)
{
printf("Usage: font [-f fontname] [-s string]\n");
exit(-1);
}
int main(int argc, char **argv)
{
XEvent event;
int i;
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
switch(argv[i][1]) {
case 'f':
fontName = argv[++i];
break;
case 's':
theString = argv[++i];
break;
default:
usage();
break;
}
} else {
usage();
}
}
win = utilCreateWindow( width, height, 100, 100, None, attributes, "Gray",
argc, argv, NULL, &dpy, &vi, &cmap, &xgc );
cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
if (!glXMakeCurrent(dpy, win, cx)) {
fprintf(stderr, "Can't make window current to context\n");
return -1;
}
Init();
for (;;) {
do {
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
DoDisplay();
break;
case KeyPress:
{
char buf[100];
int rv;
KeySym ks;
rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
switch (ks) {
case XK_a:
mode = DRAW_ALL;
DoDisplay();
break;
case XK_b:
mode = DRAW_ALPHABET;
DoDisplay();
break;
case XK_r:
mode = DRAW_RAINBOW;
DoDisplay();
break;
case XK_Escape:
goto done;
break;
}
}
break;
}
} while (XPending(dpy) != 0);
}
done:
glXMakeCurrent(dpy, None, NULL);
glXDestroyContext(dpy, cx);
XCloseDisplay(dpy);
}